package com.jasony.tools.excel;

import com.jasony.tools.excel.constants.ExcelExt;
import com.jasony.tools.excel.hssf.HSSFExcelWorkBook;
import com.jasony.tools.excel.xssf.XSSFExcelWorkBook;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public abstract class ExcelWorkBook {
    private List<ExcelSheet> sheets;
    private ExcelExt ext;
    private String fileName;
    private Workbook workbook;

    protected ExcelWorkBook(ExcelExt ext) {
        sheets = new ArrayList<>();
        this.ext = ext;
    }

    public <T> ExcelWorkBook addSheet(String name, List<T> data, Class<T> clazz) {
        if (StringUtils.isBlank(name)) {
            name = "sheet" + (sheets.size() + 1);
        }
        if (Objects.isNull(data)) {
            data = new ArrayList<>();
        }
        ExcelSheet<T> sheet = createExcelSheet(name, data, clazz);
        sheets.add(sheet);
        return this;
    }

    public ExcelWorkBook setFileName(String fileName) {
        this.fileName = fileName;

        return this;
    }

    public ExcelExt getExt() {
        return this.ext;
    }

    public String getFileName() {
        return this.fileName;
    }

    public List<ExcelSheet> getSheets() {
        return this.sheets;
    }

    protected abstract <T> ExcelSheet<T> createExcelSheet(String name, List<T> data, Class<T> clazz);

    private Workbook createWorkBook() {
        switch (ext) {
            case XLS:
                return new HSSFWorkbook();
            case XLSX:
                return new SXSSFWorkbook();
        }
        throw new IllegalArgumentException(ext.name() + "not support!");
    }

    /**
     *  导出excel
     *
     * @return
     */
    public ExcelOption export()
            throws IllegalArgumentException {
        this.workbook = createWorkBook();
        for (ExcelSheet sheet : sheets) {
            sheet.writeWorkBook(workbook);
        }
        return ExcelOption.build(workbook, null);
    }

    public static ExcelWorkBook build(String fileName) {
        String[] split = fileName.split(".");
        ExcelExt excelExt = ExcelExt.XLSX;
        if (split.length > 1) {
            String ext = split[split.length - 1].toUpperCase();
            excelExt = ExcelExt.valueOf(ext);
        } else {
            fileName += "." + excelExt.name().toLowerCase();
        }
        ExcelWorkBook workBook = build(excelExt);
        workBook.setFileName(fileName);
        return workBook;
    }

    public static ExcelWorkBook build(ExcelExt ext) {
        switch (ext) {
            case XLSX:
                return new XSSFExcelWorkBook(ext);
            case XLS:
                return new HSSFExcelWorkBook(ext);
        }
        throw new IllegalArgumentException(ext.name() + " not support!");
    }
}
